/***************************************************************************
 *   Copyright (C) 2007 by James Grimwood   *
 *   james@piku.org.uk   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <stdlib.h>
#include "SDL.h"
#include "kyralib/kyra.h"
#include "../data/sprite.h"
#include <vector>
using namespace std;
using namespace grinliz;

#define SDL_TIMER_EVENT ( SDL_USEREVENT + 0 )
const int TIMER_INTERVAL = 80;

const int SCREENX = 640;
const int SCREENY = 480;
Uint32 TimerCallback(Uint32 interval)
{
        SDL_Event event;
        event.type = SDL_TIMER_EVENT;

        SDL_PeepEvents( &event, 1, SDL_ADDEVENT, 0 );
        return TIMER_INTERVAL;
}

#define TICK_INTERVAL    30

Uint32 TimeLeft(void)
{
    static Uint32 next_time = 0;
    Uint32 now;

    now = SDL_GetTicks();
    if ( next_time <= now ) {
        next_time = now+TICK_INTERVAL;
        return(0);
    }
    return(next_time-now);
}


int main(int argc, char *argv[])
{
SDL_Surface* screen;

    const SDL_version* sdlVersion = SDL_Linked_Version();
    if ( sdlVersion->minor < 2 )
    {
        printf( "SDL version must be at least 1.2.0" );
        exit( 254 );
    }
    /* Initialize the SDL library */
    if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0 )
    {
        printf( "Couldn't initialize SDL: %s\n",SDL_GetError());
        exit(255);
    }
    /* Create a display for the image */
    screen = SDL_SetVideoMode( SCREENX, SCREENY, 0, SDL_HWSURFACE );
    if ( screen == NULL ) {
        exit(3);
    }

    KrEngine* engine = new KrEngine( screen );
    engine->Draw();

    // Load the dat file.
    // The dat file was carefully created in the sprite
    // editor. Loading allows us access to the
    // MAGE, PARTICLE, and CARPET.
    if ( !engine->Vault()->LoadDatFile( "sprite.dat" ) )
    {
        printf( "Error loading the tutorial dat file\n" );
        exit( 255 );
    }

    // Get the CARPET resource
    KrSpriteResource* shipRes = engine->Vault()->GetSpriteResource( TEST_ship );
    GLASSERT( shipRes );

    // Create the carpet sprite and add it to the tree
    KrSprite* ship = new KrSprite( shipRes );
    ship->SetPos( SCREENX / 2, SCREENY / 2 );
    engine->Tree()->AddNode( 0, ship );

    KrSpriteResource* ghostRes = engine->Vault()->GetSpriteResource(TEST_ship);
    GLASSERT( ghostRes );

#define GHOST_START_X SCREENX / 2
#define GHOST_START_Y SCREENY / 2
#define MAX_GHOSTS 10
    //KrSprite* ghost = new KrSprite( ghostRes );
    //ghost->SetPos( GHOST_START_X, GHOST_START_Y - 64);
    //engine->Tree()->AddNode( 0, ghost );

    vector< KrImage* > otherGhost;
    vector< KrImage* > hit;
    for (int i = 0; i < MAX_GHOSTS; ++i)
        otherGhost.push_back( new KrSprite( ghostRes ));
    for (int i = 0; i < (int)otherGhost.size(); ++i) {
        otherGhost[i]->SetPos( GHOST_START_X, GHOST_START_Y );
        engine->Tree()->AddNode( 0, otherGhost[i] );
    }

#define speed 5
#define maxspeed 15
    
    SDL_Event event;
    bool done = false;
    int sx, sy;
    float xspd = 0, yspd = 0;
    int mx, my;
    Random random;
    float xd, yd, hyp, angy, angx;
    
    ship->SetPos( SCREENX / 2, SCREENY / 2);
    sx = ship->X();
    sy = ship->Y();
    // Start timing!
    //SDL_SetTimer( TIMER_INTERVAL, TimerCallback );
    SDL_ShowCursor(SDL_DISABLE);
    SDL_WarpMouse( SCREENX / 2, SCREENY / 2);
    while( !done ) {
        while (SDL_PollEvent(&event) ) {
            if ( event.type == SDL_QUIT )
                    break;

            switch(event.type) {
                case SDL_KEYDOWN: {
                        done = true;
                } break;

                case SDL_MOUSEMOTION: {
                    SDL_GetMouseState (&mx,&my);
                    xspd = (mx - (SCREENX/2)) * 0.14;
                    yspd = (my - (SCREENY/2)) * 0.14;
                } break;

                case SDL_TIMER_EVENT: {
                        // code_d Walk the list and move the particles
                        // Move the ship.
                        //ship->DoStep();

                } break;

                default:
                    break;
            }
            


        }

        for (int i = 0; i < otherGhost.size(); ++i) {
            otherGhost[i]->SetPos( otherGhost[i]->X() + (random.Rand(3) - 1) * 5 , otherGhost[i]->Y() + ( random.Rand(3) - 1) * 5);
        }
        vector<KrImage*>::iterator itVectorData;

        // This code crashes, but also works... in a way
//         if (engine->Tree()->CheckSiblingCollision(ship, &hit, 0) ) {
//             for (int i = 0; i < (int)hit.size(); ++i) {
//                 engine->Tree()->DeleteNode(hit[i]);
//                 int count = 0;
//                 for(itVectorData = otherGhost.begin(); itVectorData != otherGhost.end(); itVectorData++)
//                 {
//                    if (*(itVectorData) == hit[i]) {
//                        printf ("Found it!\n");
//                        break;
//                    }
//                    count++;
//                 }
//                 //int j = otherGhost.Find(hit[i]);
//                 otherGhost.erase(otherGhost.begin()+count);
//             }
//             if (otherGhost.empty())
//                 done = true;
//         }
        
        sx += int(xspd);
        sy += int(yspd);
        ship->SetPos( sx, sy);
        engine->Draw();
        SDL_Delay(TimeLeft());
    }

    delete engine;

    SDL_Quit();
    return 0;
}
